package com.atguigu.tingshu.common.login;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.concurrent.TimeUnit;

@Component
@Aspect
public class TsLoginAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Around("execution(* com.atguigu.tingshu.*.api.*.*(..)) && @annotation(tsLogin)")
    public Object around(ProceedingJoinPoint joinPoint, TsLogin tsLogin) throws Throwable {
//        获取当前线程的请求上下文
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//        将请求上下文转化为ServletRequestAttributes
            ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
//        从attribute中获取到用户登录的token
            String token = attributes.getRequest().getHeader("token");
//        判断是否是必须要登录
            if (tsLogin.Required()) {
//            必须登录
//        从redis中找是否有用户信息
                if (token == null) {
//            如果获取到的token是空的就表示没有登录
                    throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
                }
//            否则就表示已经登陆了
                //  生成redis的key
                String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
//            从获取userInfo信息
                UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(loginKey);
                if (userInfo == null) {
                    throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
                }
            }
        try {
//        不管要求必须登录还是不要求必须登录都要只要
            if (token != null) {
                //  生成redis的key
                String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
//            从获取userInfo信息
                UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(loginKey);
//            判断userInfo是否为null
                if (userInfo != null) {
//            将userInfo中的id装入线程中
                    AuthContextHolder.setUserId(userInfo.getId());
                }
            }
//            执行切面原来方法体并且返回
            return joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        } finally {
//            最终要将当前登陆的用户id从当前线程中删除
            AuthContextHolder.removeUserId();
        }
    }
}
